﻿#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using System;
using System.IO.Pipes;
using System.Security.AccessControl;
using NUnitGrid.Framework.Logging;


namespace NUnitGrid.Framework.Pipes.Server
{
    public class PipeServerStreamFactory : IPipeStreamFactory
    {
        private const int maxNumberOfConnections = 100;
        private readonly IPipeConfiguration configuration;
        private readonly ILogger logger;
        private readonly IPipeStreamFactory streamFactory;

        public PipeServerStreamFactory(IPipeStreamFactory streamFactory, ILogger logger,
                                       IPipeConfiguration configuration)
        {
            this.streamFactory = streamFactory;
            this.logger = logger;
            this.configuration = configuration;
        }

        public IPipeStream Create(System.IO.Pipes.PipeStream pipeStream)
        {
            throw new InvalidOperationException();
        }

        public IPipeStream Create()
        {
            PipeSecurity pipeSecurity;
            using (
                var seedPipe = new NamedPipeServerStream(configuration.PipeName, PipeDirection.InOut,
                                                         maxNumberOfConnections,
                                                         PipeTransmissionMode.Message, PipeOptions.None, 8*1024, 16*1024)
                )
            {
                pipeSecurity = seedPipe.GetAccessControl();
            }

            var accessRule = new PipeAccessRule("Everyone", PipeAccessRights.FullControl, AccessControlType.Allow);
            pipeSecurity.AddAccessRule(accessRule);

            var pipe = new NamedPipeServerStream(configuration.PipeName, PipeDirection.InOut, maxNumberOfConnections,
                                                 PipeTransmissionMode.Message,
                                                 PipeOptions.Asynchronous, 8*1024, 16*1024, pipeSecurity);

            return new PipeServerStream(pipe, streamFactory.Create(pipe), logger);
        }
    }
}